Introduction to Tick Layer
What is a tick layer?
A tick is largely similar to a point mark except for the fact that it has a start point and an end point and thus is always a straight line.
Example
const { muze, getDataFromSearchQuery } = viz;
const data = getDataFromSearchQuery();
muze
.canvas()
.rows(["Cylinders"])
.columns(["Horsepower"])
.detail(["Name"])
.layers([
{
mark: "tick",
},
])
.data(data)
.mount("#chart");
Creating a dotplot using tick layer
Example
const { muze, getDataFromSearchQuery } = viz;
const data = getDataFromSearchQuery();
muze
.canvas()
.rows(["Acceleration"])
.columns(["Year"])
.color("Origin")
.detail(["Name"])
.layers([
{
mark: "tick",
},
])
.data(data)
.mount("#chart");
Creating a reference line
Below is an example of creating a reference line on a bar chart.
We will add a bar layer for visualizing Year vs Horsepower, a tick layer for showing the average value and a text layer displaying the actual average value.
Example
const { muze, getDataFromSearchQuery } = viz;
const data = getDataFromSearchQuery();
let dm = new DataModel(data);
dm = dm.groupBy(["Year"]);
dm = dm.sort([["Horsepower", "DESC"]]);
let layerFactory = muze.layerFactory;
// Compose layers to draw the bars as well as the reference line and text
layerFactory.composeLayers("compositeBar", [
{
name: "simplebar",
mark: "bar",
encoding: {
x: "compositeBar.encoding.x",
y: "compositeBar.encoding.y",
color: "compositeBar.encoding.color",
},
},
{
name: "averageLine",
mark: "tick",
source: "averageLine",
className: "averageLine",
encoding: {
y: "compositeBar.encoding.y",
x: null,
},
calculateDomain: false,
},
{
name: "averageText",
mark: "text",
source: "averageLine",
className: "averageText",
encoding: {
y: "compositeBar.encoding.y",
text: "compositeBar.encoding.text",
background: {
enabled: true,
},
},
encodingTransform: (points, layer, dependencies) => {
// Transforms the test after the physical dimension is resolved so that it comes in the middle of the background
let width = layer.measurement().width;
let smartLabel = dependencies.smartLabel;
for (let i = 0; i < points.length; i++) {
let size = smartLabel.getOriSize(points[i].text);
points[i].update.x = width - 5;
points[i].textanchor = "end";
points[i].update.y -= size.height / 2;
points[i].color = "#000";
}
return points;
},
calculateDomain: false,
},
]);
muze
.canvas()
.rows(["Horsepower"])
.columns(["Year"])
.transform({
// Create different sources (data) from the root source (data). Layers can access these sources and draw any visualization
averageLine: (dt) => dt.groupBy([""]), // Removes all the dim and aggregate the measures
})
.layers([
{
mark: "bar",
},
{
mark: "text",
encoding: {
x: {
field: null,
value: (d, i) => {
return i.context.measurement().width - 80;
},
},
y: {
field: "Horsepower",
value: (d) => {
return d.y - 10;
},
},
text: {
field: "Horsepower",
formatter: (value) => {
return `Average Horsepower: ${Math.round(value)}`;
},
},
color: {
value: () => "black",
},
},
source: "averageLine",
},
{
mark: "tick",
className: "averageLine",
encoding: {
x: {
field: null,
},
y: "Horsepower",
color: {
value: () => "black",
},
},
source: "averageLine",
},
])
.title("Sorted bar with trendline", { position: "top", align: "left" })
.subtitle(
"Average horsepower per year with average horsepower of all time marked as reference",
{ position: "top", align: "left" },
)
.data(dm)
.mount("#chart");